﻿using System;
using System.ComponentModel;
using System.Diagnostics;
using Socium.Domain;

namespace Socium.Presentation {
	/// <summary>
	/// Base class for all ViewModel classes in the application.
	/// It provides support for property change notifications 
	/// and has a DisplayName property.  This class is abstract.
	/// </summary>
	public abstract class ViewModelBase : Disposable, INotifyPropertyChanged {
		#region Debugging Aides

		/// <summary>
		/// Warns the developer if this object does not have
		/// a public property with the specified name. This 
		/// method does not exist in a Release build.
		/// </summary>
		[Conditional("DEBUG")]
		[DebuggerStepThrough]
		public void VerifyPropertyName(string property_name) {
			// Verify that the property name matches a real,  
			// public, instance property on this object.
			if (TypeDescriptor.GetProperties(this)[property_name] == null) {
				throw new Exception("Invalid property name: " + property_name);
			}
		}

		#endregion // Debugging Aides

		#region INotifyPropertyChanged Members

		/// <summary>
		/// Raised when a property on this object has a new value.
		/// </summary>
		public event PropertyChangedEventHandler PropertyChanged;

		/// <summary>
		/// Raises this object's PropertyChanged event.
		/// </summary>
		/// <param name="property_name">The property that has a new value.</param>
		protected virtual void OnPropertyChanged(string property_name) {
			VerifyPropertyName(property_name);

			var handler = PropertyChanged;
			if (handler != null) {
				var e = new PropertyChangedEventArgs(property_name);
				handler(this, e);
			}
		}

		#endregion // INotifyPropertyChanged Members

		protected override void Dispose(bool disposing) {
			//#if DEBUG
			//if (!disposing) {
			//    var message = string.Format("{0} ({1}) Finalized", GetType().Name, GetHashCode());
			//    Debug.WriteLine(message);
			//}
			//#endif	
		}
	}
}